// 1.在ts中，类是结构化类型,但是需要注意访问修饰符会触发ts类型检查
// 2.在ts中，类既声明值也声明类型，而且类的类型有两种：实例化对象类型，类构造函数类型
/* class User{
  constructor(public id: number, public name: string) { }
  show(addr: string) {
    console.log(addr);
  }
}

class Person{
  constructor(public id: number, public name: string, private sex: string) { }
  show(addr: string) {
    console.log(this.id + "---" + this.name + "---" + addr);
  }
}

function desc(user: User) {
  user.show("成都");
}

const u = new User(1, "jack");
const p = new Person(2, "john", "男");

const a = {
  id: 3,
  name: "ruby",
  tel:"13111111111",
  show(addr: string): void{
    console.log("hello " + addr);
  }
}

desc(u);
desc(p);
desc(a);
// desc({ id: 4, name: 'rose', tel:"1322222", show(addr:string) { console.log("addr" + addr)} }) */


class MyMap{
  state: Record<string, string> = {};

  get(key: string): string | undefined{
    return this.state[key];
  }

  set(key: string, value: string): void{
    this.state[key] = value;
  }

  values(): string[]{
    return Object.values(this.state);
  }

  keys(): string[]{
    return Object.keys(this.state);
  }

  static of(...entries: [string, string][]): MyMap{
    const map = new MyMap();
    entries.forEach(entry => map.set(entry[0], entry[1]));
    return map;
  }
}

const m1:MyMap = new MyMap();
m1.set("id", "1");
m1.set("name", "jack");
console.log(m1.get("name"));
console.log(m1.values());

const m2 = MyMap.of(["name", "rose"], ["sex", "女"]);
console.log(m2.keys());


class User{
  constructor(public id: number, public name: string) { }
  show(addr: string) {
    console.log(addr);
  }
}

function method1(target: User) {
  console.log(target.id);
  console.log(target.name);
  target.show("北京");
}

//method2需要一个类，在函数中对类进行处理
// 类的构造函数类型  new (...args: any[]) => any
function method2(target: new (...args:[number, string]) => User) {
  const t = new target(1, "jack");
  console.log(t.id);
  console.log(t.name);
  t.show("北京");
}

// 构造函数类型的表示
type MyMapConstructorType = typeof MyMap;
// 通过构造函数类型获取实例化类型
type MyMapInstanceType = InstanceType<MyMapConstructorType>;

const m3: MyMapInstanceType = new MyMap();

// const m = new Map();

//MyMap的实例化类型
interface MyMap{
  state: Record<string, string>;
  get(key: string): string | undefined;
  set(key: string, value: string): void;
  values(): string[];
  keys(): string[];
}

// MyMap的构造函数类型
interface MyMapConstructor{
  new(): MyMap;
  of(...entries: [string, string][]): MyMap;
  readonly prototype: MyMap;
}

let m: MyMapConstructor;
type M1 = typeof m;
type M2 = InstanceType<M1>;


class Person{
  constructor(public name: string){}
}

type PersonInstance = InstanceType<typeof Person>;
const person: PersonInstance = new Person("jack");

interface UserConstructor{
  new(name: string): User;
}

type UserInstance = InstanceType<UserConstructor>;